// 二倍均值算法
// 优势在于不需要先把每个人得多少算出来，只有拆红包的时候才会算出这个人得多少，减少实时算力
// 同时保证了每个人拼手气得到的平均值相同
// 设有10个人，红包总额100元。
// 100/10X2 = 20, 所以第一个人的随机范围是（0，20 )，平均可以抢到10元。
// 假设第一个人随机到10元，那么剩余金额是100-10 = 90 元。
// 90/9X2 = 20, 所以第二个人的随机范围同样是（0，20 )，平均可以抢到10元。
// 假设第二个人随机到10元，那么剩余金额是90-10 = 80 元。
// 80/8X2 = 20, 所以第三个人的随机范围同样是（0，20 )，平均可以抢到10元。
// count 红包数量，amout 红包金额
package main

import (
	"fmt"
	"math/rand"
	"time"
)

// 提前定义能抢到的最小金额1分
var min int64 = 1

// 二倍均值算法
func DoubleAverage(count, amount int64) int64 {
	if count == 1 {
		return amount
	}
	//计算出最大可用金额
	max := amount - min*count //计算出最大可用平均值
	avg := max / count        //二倍均值基础上再加上最小金额 防止出现金额为0
	avg2 := 2*avg + min       //随机红包金额序列元素，把二倍均值作为随机的最大数
	rand.Seed(time.Now().UnixNano())
	x := rand.Int63n(avg2) + min
	return x
}

func main() {
	//10个人 抢10000分  也就是10个人抢100块钱
	count, amount := int64(10), int64(10000)
	remain := amount
	sum := int64(0)
	for i := int64(0); i < count; i++ {
		x := DoubleAverage(count-i, remain)
		remain -= x
		sum += x
		fmt.Println(i+1, "=", float64(x)/float64(100), ", ")
	}
	fmt.Println()
	fmt.Println("总和是:", sum)
}
